home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / gcc_260.zip / gcc_260 / bc-emit.c < prev    next >
C/C++ Source or Header  |  1994-06-14  |  21KB  |  992 lines

  1. /* Output bytecodes for GNU C-compiler.
  2.    Copyright (C) 1993, 1994 Free Software Foundation, Inc.
  3.  
  4. This file is part of GNU CC.
  5.  
  6. GNU CC is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. GNU CC is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GNU CC; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20.  
  21. #include "config.h"
  22. #ifdef __STDC__
  23. #include <stdarg.h>
  24. #else
  25. #include <varargs.h>
  26. #endif
  27. #include "machmode.h"
  28. #include "rtl.h"
  29. #include "real.h"
  30. #include "obstack.h"
  31. #include "bytecode.h"
  32. #ifdef __GNUC__
  33. #include "bytetypes.h"
  34. #endif
  35. #include "bc-emit.h"
  36. #include "bc-opcode.h"
  37. #include "bc-typecd.h"
  38. #include "bi-run.h"
  39.  
  40. #include <stdio.h>
  41.  
  42. extern char *xmalloc (), *xrealloc ();
  43. extern void free ();
  44.  
  45. extern struct obstack *rtl_obstack;
  46.  
  47. /* Indexed by mode class, gives the narrowest mode for each class.  */
  48.  
  49. extern enum machine_mode class_narrowest_mode[(int) MAX_MODE_CLASS];
  50.  
  51. /* Commonly used modes.  */
  52. /* Mode whose width is BITS_PER_UNIT */
  53. extern enum machine_mode byte_mode;
  54.  
  55. /* Mode whose width is BITS_PER_WORD */
  56. extern enum machine_mode word_mode;
  57.  
  58. /* Vector indexed by opcode giving info about the args for each opcode. */
  59. static struct arityvec arityvec[] = {
  60. #include "bc-arity.h"
  61. };
  62.  
  63. /* How to print a symbol name for the assembler.  */
  64. static void
  65. prsym (file, s)
  66.      FILE *file;
  67.      char *s;
  68. {
  69.   if (*s == '*')
  70.     fprintf (file, "%s", s + 1);
  71.   else
  72.  
  73. #ifdef NAMES_HAVE_UNDERSCORES
  74.     fprintf (file, "_%s", s);
  75. #else
  76.     fprintf (file, "%s", s);
  77. #endif
  78.  
  79. }
  80.  
  81. /* Maintain a bucket hash table for symbol names. */
  82.  
  83. #define HASH_BITS 32
  84. #define HASH_SIZE 509
  85.  
  86. static struct bc_sym *hashtab[HASH_SIZE];
  87.  
  88. static unsigned int
  89. hash (name)
  90.      char *name;
  91. {
  92.   unsigned int hash = 0;
  93.  
  94.   while (*name)
  95.     {
  96.       hash = hash << 3 | hash >> HASH_BITS - 3;
  97.       hash += *name++;
  98.     }
  99.  
  100.   return hash % HASH_SIZE;
  101. }
  102.  
  103.  
  104. /* Look up the named symbol, creating it if it doesn't exist. */
  105. struct bc_sym *
  106. sym_lookup (name)
  107.      char *name;
  108. {
  109.   int i;
  110.   struct bc_sym *s;
  111.  
  112.   i = hash (name);
  113.   for (s = hashtab[i]; s; s = s->next)
  114.     if (!strcmp (s->name, name))
  115.       return s;
  116.  
  117.   s = (struct bc_sym *) xmalloc (sizeof (struct bc_sym));
  118.   s->name = xmalloc (strlen (name) + 1);
  119.   strcpy (s->name, name);
  120.   s->defined = s->global = s->common = 0;
  121.   s->val = 0;
  122.   s->next = hashtab[i];
  123.   hashtab[i] = s;
  124.   return s;
  125. }
  126.  
  127.  
  128. /* Write out .globl and common symbols to the named file.  */
  129. static void
  130. bc_sym_write (file)
  131.      FILE *file;
  132. {
  133.   int i;
  134.   struct bc_sym *s;
  135.  
  136.   for (i = 0; i < HASH_SIZE; ++i)
  137.     for (s = hashtab[i]; s; s = s->next)
  138.       {
  139.     if (s->global)
  140.       {
  141.         fprintf (file, "\n\t.globl ");
  142.         prsym (file, s->name);
  143.         putc ('\n', file);
  144.         if (s->common)
  145.           {
  146.         fprintf (file, "\n\t.comm ");
  147.         prsym (file, s->name);
  148.         fprintf (file, ", %d\n", s->val);
  149.           }
  150.       }
  151.     else if (s->common)
  152.       {
  153.         fprintf (file, "\n\t.lcomm ");
  154.         prsym (file, s->name);
  155.         fprintf (file, ", %d\n", s->val);
  156.       }
  157.       }
  158. }
  159.  
  160.  
  161.  
  162.  
  163. /* Create and initialize a new segment. */
  164. static struct bc_seg *
  165. seg_create ()
  166. {
  167.   struct bc_seg *result;
  168.  
  169.   result = (struct bc_seg *) xmalloc (sizeof (struct bc_seg));
  170.   result->alloc = 256;
  171.   result->data = xmalloc (result->alloc);
  172.   result->size = 0;
  173.   result->syms = 0;
  174.   result->relocs = 0;
  175.   return result;
  176. }
  177.  
  178.  
  179. /* Advance the segment index to the next alignment boundary. */
  180. static void
  181. seg_align (seg, log)
  182.      struct bc_seg *seg;
  183.      int log;
  184. {
  185.   unsigned int oldsize = seg->size;
  186.  
  187.   seg->size = seg->size + (1 << log) - 1 & ~((1 << log) - 1);
  188.   if (seg->size > seg->alloc)
  189.     {
  190.       while (seg->size > seg->alloc)
  191.     seg->alloc *= 2;
  192.       seg->data = xrealloc (seg->data, seg->alloc);
  193.     }
  194.   bzero (seg->data + oldsize, seg->size - oldsize);
  195. }
  196.  
  197.  
  198. /* Append the given data to the given segment. */
  199. static void
  200. seg_data (seg, data, size)
  201.      struct bc_seg *seg;
  202.      char *data;
  203.      unsigned int size;
  204. {
  205.   if (seg->size + size > seg->alloc)
  206.     {
  207.       while (seg->size + size > seg->alloc)
  208.     seg->alloc *= 2;
  209.       seg->data = xrealloc (seg->data, seg->alloc);
  210.     }
  211.  
  212.   bcopy (data, seg->data + seg->size, size);
  213.   seg->size += size;
  214. }
  215.  
  216.  
  217. /* Append a zero-filled skip to the given segment.  */
  218. static void
  219. seg_skip (seg, size)
  220.      struct bc_seg *seg;
  221.      unsigned int size;
  222. {
  223.   if (seg->size + size > seg->alloc)
  224.     {
  225.       while (seg->size + size > seg->alloc)
  226.     seg->alloc *= 2;
  227.       seg->data = xrealloc (seg->data, seg->alloc);
  228.     }
  229.  
  230.   memset (seg->data + seg->size, 0, size);
  231.   seg->size += size;
  232. }
  233.  
  234.  
  235. /* Define the given name as the current offset in the given segment.  It
  236.    is an error if the name is already defined.  Return 0 or 1 indicating
  237.    failure or success respectively. */
  238. static int
  239. seg_defsym (seg, name)
  240.      struct bc_seg *seg;
  241.      char *name;
  242. {
  243.   struct bc_sym *sym;
  244.   struct bc_segsym *segsym;
  245.  
  246.   sym = sym_lookup (name);
  247.   if (sym->defined)
  248.     return 0;
  249.  
  250.   sym->defined = 1;
  251.   sym->val = seg->size;
  252.   segsym = (struct bc_segsym *) xmalloc (sizeof (struct bc_segsym));
  253.   segsym->sym = sym;
  254.   segsym->next = seg->syms;
  255.   seg->syms = segsym;
  256.   return 1;
  257. }
  258.  
  259.  
  260. /* Generate in seg's data a reference to the given sym, adjusted by
  261.    the given offset. */
  262. static void
  263. seg_refsym (seg, name, offset)
  264.      struct bc_seg *seg;
  265.      char *name;
  266.      int offset;
  267. {
  268.   struct bc_sym *sym;
  269.   struct bc_segreloc *segreloc;
  270.  
  271.   sym = sym_lookup (name);
  272.   segreloc = (struct bc_segreloc *) xmalloc (sizeof (struct bc_segreloc));
  273.   segreloc->offset = seg->size;
  274.   segreloc->sym = sym;
  275.   segreloc->next = seg->relocs;
  276.   seg->relocs = segreloc;
  277.   seg_data (seg, (char *) &offset, sizeof offset);
  278. }
  279.  
  280.  
  281. /* Concatenate the contents of given segments into the first argument. */
  282. static void
  283. seg_concat (result, seg)
  284.      struct bc_seg *result, *seg;
  285. {
  286.   unsigned int fix;
  287.   struct bc_segsym *segsym;
  288.   struct bc_segreloc *segreloc;
  289.  
  290.   seg_align (result, MACHINE_SEG_ALIGN);
  291.   fix = result->size;
  292.   seg_data (result, seg->data, seg->size);
  293.   free (seg->data);
  294.  
  295.   /* Go through the symbols and relocs of SEG, adjusting their offsets
  296.      for their new location in RESULT. */
  297.   if (seg->syms)
  298.     {
  299.       segsym = seg->syms;
  300.       do
  301.     segsym->sym->val += fix;
  302.       while (segsym->next && (segsym = segsym->next));
  303.       segsym->next = result->syms;
  304.       result->syms = seg->syms;
  305.     }
  306.   if (seg->relocs)
  307.     {
  308.       segreloc = seg->relocs;
  309.       do
  310.     segreloc->offset += fix;
  311.       while (segreloc->next && (segreloc = segreloc->next));
  312.       segreloc->next = result->relocs;
  313.       result->relocs = seg->relocs;
  314.     }
  315.  
  316.   free ((char *) seg);
  317. }
  318.  
  319. /* Write a segment to a file.  */
  320. static void
  321. bc_seg_write (seg, file)
  322.      struct bc_seg *seg;
  323.      FILE *file;
  324. {
  325.   struct bc_segsym *segsym, *nsegsym, *psegsym;
  326.   struct bc_segreloc *segreloc, *nsegreloc, *psegreloc;
  327.   int i, offset, flag;
  328.  
  329.   /* Reverse the list of symbols.  */
  330.   for (psegsym = 0, segsym = seg->syms; segsym; segsym = nsegsym)
  331.     {
  332.       nsegsym = segsym->next;
  333.       segsym->next = psegsym;
  334.       psegsym = segsym;
  335.     }
  336.   seg->syms = psegsym;
  337.  
  338.   /* Reverse the list of relocs.  */
  339.   for (psegreloc = 0, segreloc = seg->relocs; segreloc; segreloc = nsegreloc)
  340.     {
  341.       nsegreloc = segreloc->next;
  342.       segreloc->next = psegreloc;
  343.       psegreloc = segreloc;
  344.     }
  345.   seg->relocs = psegreloc;
  346.  
  347.   /* Output each byte of the segment.  */
  348.   for (i = 0, segsym = seg->syms, segreloc = seg->relocs; i < seg->size; ++i)
  349.     {
  350.       while (segsym && segsym->sym->val == i)
  351.     {
  352.       if (i % 8 != 0)
  353.         putc ('\n', file);
  354.  
  355.       BC_WRITE_SEGSYM (segsym, file);
  356.       segsym = segsym->next;
  357.       flag = 1;
  358.     }
  359.       if (segreloc && segreloc->offset == i)
  360.     {
  361.       if (i % 8 != 0)
  362.         putc ('\n', file);
  363.  
  364.       bcopy (seg->data + i, (char *) &offset, sizeof (int));
  365.       i += sizeof (int) - 1;
  366.  
  367.       BC_WRITE_RELOC_ENTRY (segreloc, file, offset);
  368.       segreloc = segreloc->next;
  369.       flag = 1;
  370.     }
  371.       else
  372.     {
  373.       if (i % 8 == 0 || flag)
  374.         BC_START_BYTECODE_LINE (file);
  375.  
  376.       BC_WRITE_BYTECODE (i % 8 == 0 || flag ? ' ' : ',',
  377.                  seg->data[i] & 0xFF,
  378.                  file);
  379.       flag = 0;
  380.       if (i % 8 == 7)
  381.         putc ('\n', file);
  382.     }
  383.     }
  384.  
  385.   /* Paranoia check--we should have visited all syms and relocs during
  386.      the output pass.  */
  387.  
  388.   if (segsym || segreloc)
  389.     abort ();
  390. }
  391.  
  392.  
  393.  
  394. /* Text and data segments of the object file in making. */
  395. static struct bc_seg *bc_text_seg;
  396. static struct bc_seg *bc_data_seg;
  397.  
  398. /* Called before anything else in this module. */
  399. void
  400. bc_initialize ()
  401. {
  402.   int min_class_size[(int) MAX_MODE_CLASS];
  403.   enum machine_mode mode;
  404.   int i;
  405.  
  406.   bc_init_mode_to_code_map ();
  407.  
  408.   bc_text_seg = seg_create ();
  409.   bc_data_seg = seg_create ();
  410.  
  411.   dconst0 = REAL_VALUE_ATOF ("0", DFmode);
  412.   dconst1 = REAL_VALUE_ATOF ("1", DFmode);
  413.   dconst2 = REAL_VALUE_ATOF ("2", DFmode);
  414.   dconstm1 = REAL_VALUE_ATOF ("-1", DFmode);
  415.  
  416.   /* Find the narrowest mode for each class and compute the word and byte
  417.      modes.  */
  418.  
  419.   for (i = 0; i < (int) MAX_MODE_CLASS; i++)
  420.     min_class_size[i] = 1000;
  421.  
  422.   for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
  423.        mode = (enum machine_mode) ((int) mode + 1))
  424.     {
  425.       if (GET_MODE_SIZE (mode) < min_class_size[(int) GET_MODE_CLASS (mode)])
  426.     {
  427.       class_narrowest_mode[(int) GET_MODE_CLASS (mode)] = mode;
  428.       min_class_size[(int) GET_MODE_CLASS (mode)] = GET_MODE_SIZE (mode);
  429.     }
  430.       if (GET_MODE_CLASS (mode) == MODE_INT
  431.       && GET_MODE_BITSIZE (mode) == BITS_PER_UNIT)
  432.     byte_mode = mode;
  433.  
  434.       if (GET_MODE_CLASS (mode) == MODE_INT
  435.       && GET_MODE_BITSIZE (mode) == BITS_PER_WORD)
  436.     word_mode = mode;
  437.     }
  438. }
  439.  
  440.  
  441. /* External addresses referenced in a function.  Rather than trying to
  442.    work relocatable address directly into bytecoded functions (which would
  443.    require us to provide hairy location info and possibly obey alignment
  444.    rules imposed by the architecture) we build an auxilary table of
  445.    pointer constants, and encode just offsets into this table into the
  446.    actual bytecode. */
  447. static struct bc_seg *ptrconsts;
  448.  
  449. /* Trampoline code for the function entry.  */
  450. struct bc_seg *trampoline;
  451.  
  452. /* Actual byte code of the function. */
  453. struct bc_seg *bytecode;
  454.  
  455. /* List of labels defined in the function. */
  456. struct bc_label *labels;
  457.  
  458. /* List of label references in the function. */
  459. struct bc_labelref *labelrefs;
  460.  
  461.  
  462. /* Add symbol to pointer table.  Return offset into table where
  463.    pointer was stored.  The offset usually goes into the bytecode
  464.    stream as a constP literal. */
  465. int
  466. bc_define_pointer (p)
  467.      char *p;
  468. {
  469.   int offset = ptrconsts->size;
  470.  
  471.   seg_refsym (ptrconsts, p, 0);
  472.   return offset;
  473. }
  474.  
  475.  
  476. /* Begin a bytecoded function.  */
  477. int
  478. bc_begin_function (name)
  479.     char *name;
  480. {
  481.   ptrconsts = seg_create ();
  482.   trampoline = seg_create ();
  483.   bytecode = seg_create ();
  484.   return seg_defsym (trampoline, name);
  485. }
  486.  
  487.  
  488. /* Force alignment in inline bytecode.  */
  489. void
  490. bc_align_bytecode (align)
  491.     int align;
  492. {
  493.   seg_align (bytecode, align);
  494. }
  495.  
  496.  
  497. /* Emit data inline into bytecode.  */
  498. void
  499. bc_emit_bytecode_const (data, size)
  500.      char *data;
  501.      unsigned int size;
  502. {
  503.   if (bytecode)
  504.     seg_data (bytecode, data, size);
  505. }
  506.  
  507.  
  508. /* Create a new "bytecode label", to have its value defined later.
  509.    Bytecode labels have nothing to do with the object file symbol table,
  510.    and are purely local to a given bytecoded function. */
  511. struct bc_label *
  512. bc_get_bytecode_label ()
  513. {
  514.   struct bc_label *result;
  515.  
  516.   result = (struct bc_label *) xmalloc (sizeof (struct bc_label));
  517.   result->defined = 0;
  518.   result->next = labels;
  519.   result->uid = 0;
  520.   labels = result;
  521.   return result;
  522. }
  523.  
  524.  
  525. /* Define the given label with the current location counter. */
  526. int
  527. bc_emit_bytecode_labeldef (label)
  528.      struct bc_label *label;
  529. {
  530.   extern int bc_new_uid ();
  531.  
  532.   if (!label || label->defined)
  533.     return 0;
  534.  
  535.   label->offset = bytecode->size;
  536.   label->defined = 1;
  537.   label->uid = bc_new_uid ();
  538.  
  539. #ifdef DEBUG_PRINT_CODE
  540.   fprintf (stderr, "$%lx:\n", label);
  541. #endif
  542.  
  543.   return 1;
  544. }
  545.  
  546.  
  547. /* Generate a location-relative reference to the given bytecode label.
  548.    It need not be defined yet; label references will be backpatched later. */
  549. void
  550. bc_emit_bytecode_labelref (label)
  551.      struct bc_label *label;
  552. {
  553.   struct bc_labelref *labelref;
  554.   static int zero;
  555.  
  556.   labelref = (struct bc_labelref *) xmalloc (sizeof (struct bc_labelref));
  557.   labelref->label = label;
  558.   labelref->offset = bytecode->size;
  559.   labelref->next = labelrefs;
  560.   labelrefs = labelref;
  561.  
  562. #ifdef DEBUG_PRINT_CODE
  563.   fprintf (stderr, " $%lx", label);
  564. #endif
  565.  
  566.   seg_data (bytecode, (char *) &zero, sizeof zero);
  567. }
  568.  
  569.  
  570. /* Emit a reference to an external address; generate the reference in the
  571.    ptrconst area, and emit an offset in the bytecode. */
  572. void
  573. bc_emit_code_labelref (name, offset)
  574.      char *name;
  575.      int offset;
  576. {
  577.   int ptroff;
  578.  
  579.   ptroff = ptrconsts->size / sizeof (char *);
  580.   seg_data (bytecode, (char *) &ptroff, sizeof ptroff);
  581.   seg_refsym (ptrconsts, name, offset);
  582.  
  583. #ifdef DEBUG_PRINT_CODE
  584.   fprintf (stderr, " [external <%x> %s]", ptroff, name);
  585. #endif
  586. }
  587.  
  588.  
  589. /* Backpatch label references in the byte code, and concatenate the bytecode
  590.    and pointer constant segments to the cumulative text for the object file.
  591.    Return a label name for the pointer constants region.  */
  592. char *
  593. bc_end_function ()
  594. {
  595.   int addr;
  596.   struct bc_label *label, *next;
  597.   struct bc_labelref *ref, *nextref;
  598.   char ptrconsts_label[20];
  599.   static int nlab;
  600.  
  601.   /* Backpatch bytecode label references. */
  602.   for (ref = labelrefs; ref; ref = ref->next)
  603.     if (ref->label->defined)
  604.       {
  605.     addr = ref->label->offset;
  606.     bcopy ((char *) &addr, bytecode->data + ref->offset, sizeof addr);
  607.       }
  608.  
  609.   /* Free the chains of labelrefs and labeldefs. */
  610.   for (ref = labelrefs; ref; ref = nextref)
  611.     {
  612.       nextref = ref->next;
  613.       free ((char *) ref);
  614.     }
  615.  
  616.   for (label = labels; label; label = next)
  617.     {
  618.       next = label->next;
  619.       free ((char *) label);
  620.     }
  621.  
  622.   seg_concat (trampoline, bytecode);
  623.   seg_align (trampoline, MACHINE_SEG_ALIGN);
  624.   sprintf (ptrconsts_label, "*LP%d", nlab++);
  625.   seg_defsym (trampoline, ptrconsts_label);
  626.   seg_concat (trampoline, ptrconsts);
  627.   seg_concat (bc_text_seg, trampoline);
  628.  
  629.   labels = 0;
  630.   labelrefs = 0;
  631.   trampoline = 0;
  632.   bytecode = 0;
  633.   ptrconsts = 0;
  634.  
  635.   return sym_lookup (ptrconsts_label)->name;
  636. }
  637.  
  638. /* Force alignment in const data. */
  639. void
  640. bc_align_const (align)
  641.      int align;
  642. {
  643.   seg_align (bc_text_seg, align);
  644. }
  645.  
  646. /* Emit const data. */
  647. void
  648. bc_emit_const (data, size)
  649.      char *data;
  650.      unsigned int size;
  651. {
  652.   seg_data (bc_text_seg, data, size);
  653. }
  654.  
  655. /* Emit a zero-filled constant skip. */
  656. void
  657. bc_emit_const_skip (size)
  658.      unsigned int size;
  659. {
  660.   seg_skip (bc_text_seg, size);
  661. }
  662.  
  663. /* Emit a label definition in const data. */
  664. int
  665. bc_emit_const_labeldef (name)
  666.      char *name;
  667. {
  668.   return seg_defsym (bc_text_seg, name);
  669. }
  670.  
  671. /* Emit a label reference in const data. */
  672. void
  673. bc_emit_const_labelref (name, offset)
  674.      char *name;
  675.      int offset;
  676. {
  677.   seg_refsym (bc_text_seg, name, offset);
  678. }
  679.  
  680. /* Force alignment in data. */
  681. void
  682. bc_align_data (align)
  683.      int align;
  684. {
  685.   seg_align (bc_data_seg, align);
  686. }
  687.  
  688. /* Emit data. */
  689. void
  690. bc_emit_data (data, size)
  691.      char *data;
  692.      unsigned int size;
  693. {
  694.   seg_data (bc_data_seg, data, size);
  695. }
  696.  
  697. /* Emit a zero-filled data skip.  */
  698. void
  699. bc_emit_data_skip (size)
  700.      unsigned int size;
  701. {
  702.   seg_skip (bc_data_seg, size);
  703. }
  704.  
  705. /* Emit label definition in data. */
  706. int
  707. bc_emit_data_labeldef (name)
  708.      char *name;
  709. {
  710.   return seg_defsym (bc_data_seg, name);
  711. }
  712.  
  713. /* Emit label reference in data. */
  714. void
  715. bc_emit_data_labelref (name, offset)
  716.      char *name;
  717.      int offset;
  718. {
  719.   seg_refsym (bc_data_seg, name, offset);
  720. }
  721.  
  722. /* Emit a common block of the given name and size.  Note that
  723.    when the .o file is actually written non-global "common"
  724.    blocks will have to be turned into space in the data section.  */
  725. int
  726. bc_emit_common (name, size)
  727.      char *name;
  728.      unsigned int size;
  729. {
  730.   struct bc_sym *sym;
  731.  
  732.   sym = sym_lookup (name);
  733.   if (sym->defined)
  734.     return 0;
  735.  
  736.   sym->defined = 1;
  737.   sym->common = 1;
  738.   sym->val = size;
  739.   return 1;
  740. }
  741.  
  742. /* Globalize the given label. */
  743. void
  744. bc_globalize_label (name)
  745.      char *name;
  746. {
  747.   struct bc_sym *sym;
  748.  
  749.   sym = sym_lookup (name);
  750.   sym->global = 1;
  751. }
  752.  
  753. static enum { in_text, in_data } section = in_text;
  754.  
  755. void
  756. bc_text ()
  757. {
  758.   section = in_text;
  759. }
  760.  
  761. void
  762. bc_data ()
  763. {
  764.   section = in_data;
  765. }
  766.  
  767. void
  768. bc_align (align)
  769.      int align;
  770. {
  771.   if (section == in_text)
  772.     bc_align_const (align);
  773.   else
  774.     bc_align_data (align);
  775. }
  776.  
  777. void
  778. bc_emit (data, size)
  779.      char *data;
  780.      unsigned int size;
  781. {
  782.   if (section == in_text)
  783.     bc_emit_const (data, size);
  784.   else
  785.     bc_emit_data (data, size);
  786. }
  787.  
  788. void
  789. bc_emit_skip (size)
  790.      unsigned int size;
  791. {
  792.   if (section == in_text)
  793.     bc_emit_const_skip (size);
  794.   else
  795.     bc_emit_data_skip (size);
  796. }
  797.  
  798. int
  799. bc_emit_labeldef (name)
  800.      char *name;
  801. {
  802.   if (section == in_text)
  803.     return bc_emit_const_labeldef (name);
  804.   else
  805.     return bc_emit_data_labeldef (name);
  806. }
  807.  
  808. void
  809. bc_emit_labelref (name, offset)
  810.      char *name;
  811.      int offset;
  812. {
  813.   if (section == in_text)
  814.     bc_emit_const_labelref (name, offset);
  815.   else
  816.     bc_emit_data_labelref (name, offset);
  817. }
  818.  
  819. void
  820. bc_write_file (file)
  821.      FILE *file;
  822. {
  823.   BC_WRITE_FILE (file);
  824. }
  825.  
  826.  
  827. /* Allocate a new bytecode rtx.
  828.    If you supply a null BC_LABEL, we generate one.  */
  829.  
  830. rtx
  831. bc_gen_rtx (label, offset, bc_label)
  832.      char *label;
  833.      int offset;
  834.      struct bc_label *bc_label;
  835. {
  836.   rtx r;
  837.  
  838.   if (bc_label == 0)
  839.     bc_label = (struct bc_label *) xmalloc (sizeof (struct bc_label));
  840.  
  841.   r = gen_rtx (CODE_LABEL, VOIDmode, label, bc_label);
  842.   bc_label->offset = offset;
  843.  
  844.   return r;
  845. }
  846.  
  847.  
  848. /* Print bytecode rtx */
  849. void
  850. bc_print_rtl (fp, r)
  851.      FILE *fp;
  852.      rtx r;
  853. {
  854. #if 0 /* This needs to get fixed to really work again.  */
  855.   /* BC_WRITE_RTL has a definition
  856.      that doesn't even make sense for this use.  */
  857.   BC_WRITE_RTL (r, fp);
  858. #endif
  859. }
  860.  
  861.  
  862. /* Emit a bytecode, keeping a running tally of the stack depth.  */
  863. void
  864. bc_emit_bytecode (bytecode)
  865.      enum bytecode_opcode bytecode;
  866. {
  867.   char byte;
  868.   static int prev_lineno = -1;
  869.  
  870.   byte = bytecode;
  871.  
  872. #ifdef BCDEBUG_PRINT_CODE
  873.   if (lineno != prev_lineno)
  874.     {
  875.       fprintf (stderr, "<line %d>\n", lineno);
  876.       prev_lineno = lineno;
  877.     }
  878.  
  879.   fputs (opcode_name[(unsigned int) bytecode], stderr);
  880. #endif
  881.  
  882.   /* Due to errors we are often requested to output bytecodes that
  883.      will cause an interpreter stack undeflow when executed.  Instead of
  884.      dumping core on such occasions, we omit the bytecode.  Erroneous code
  885.      should not be executed, regardless.  This makes life much easier, since
  886.      we don't have to deceive ourselves about the known stack depth. */
  887.  
  888.   bc_emit_bytecode_const (&byte, 1);
  889.  
  890.   if ((stack_depth -= arityvec[(int) bytecode].ninputs) >= 0)
  891.     {
  892.       if ((stack_depth += arityvec[(int) bytecode].noutputs) > max_stack_depth)
  893.     max_stack_depth = stack_depth;
  894.     }
  895.  
  896. #ifdef VALIDATE_STACK_FOR_BC
  897.   VALIDATE_STACK_FOR_BC ();
  898. #endif
  899. }
  900.  
  901.  
  902. #ifdef BCDEBUG_PRINT_CODE
  903. #define PRLIT(TYPE, PTR)  fprintf (stderr, " [%x]", *(TYPE *) PTR)
  904. #else
  905. #define PRLIT(X,Y)
  906. #endif
  907.  
  908. /* Emit a complete bytecode instruction, expecting the correct number
  909.    of literal values in the call.  First argument is the instruction, the
  910.    remaining arguments are literals of size HOST_WIDE_INT or smaller. */
  911. void
  912. bc_emit_instruction VPROTO((enum bytecode_opcode opcode, ...))
  913. {
  914. #ifndef __STDC__
  915.   enum bytecode_opcode opcode;
  916. #endif
  917.   va_list arguments;
  918.   int nliteral, instruction;
  919.  
  920.   VA_START (arguments, opcode);
  921.  
  922. #ifndef __STDC__
  923.   opcode = va_arg (arguments, enum bytecode_opcode);
  924. #endif
  925.  
  926.   /* Emit instruction bytecode */
  927.   bc_emit_bytecode (opcode);
  928.   instruction = (int) opcode;
  929.  
  930.   /* Loop literals and emit as bytecode constants */
  931.   for (nliteral = 0; nliteral < arityvec[instruction].nliterals; nliteral++)
  932.     {
  933.       switch (arityvec[instruction].literals[nliteral])
  934.     {
  935. /* This conditional is a kludge, but it's necessary
  936.    because TYPE might be long long.  */
  937. #ifdef __GNUC__
  938.       /* Expand definitions into case statements */
  939. #define DEFTYPECODE(CODE, NAME, MODE, TYPE)                \
  940.     case CODE:                            \
  941.       {                                \
  942.         TYPE temp = va_arg (arguments, TYPE);             \
  943.         bc_emit_bytecode_const ((void *) &temp, sizeof temp);     \
  944.         PRLIT (TYPE, &temp); }                    \
  945.       break;
  946.  
  947. #include "bc-typecd.def"
  948.  
  949. #undef DEFTYPECODE
  950. #endif /* __GNUC__ */
  951.  
  952.     default:
  953.       abort ();
  954.     }
  955.     }
  956.  
  957. #ifdef BCDEBUG_PRINT_CODE
  958.   fputc ('\n', stderr);
  959. #endif
  960. }
  961.  
  962. /* Emit the machine-code interface trampoline at the beginning of a byte
  963.    coded function.  The argument is a label name of the interpreter
  964.    bytecode callinfo structure; the return value is a label name for
  965.    the beginning of the actual bytecode.  */
  966. char *
  967. bc_emit_trampoline (callinfo)
  968.      char *callinfo;
  969. {
  970.   char mylab[20];
  971.   static int n;
  972.  
  973.   sprintf (mylab, "*LB%d", n++);
  974.   
  975.   BC_EMIT_TRAMPOLINE (trampoline, callinfo);
  976.  
  977.   seg_defsym (bytecode, mylab);
  978.   return sym_lookup (mylab)->name;
  979. }
  980.  
  981.  
  982. /* Simple strdup */
  983. char *
  984. bc_xstrdup (str)
  985.      char *str;
  986. {
  987.   char *tmp = xmalloc (strlen (str) + 1);
  988.  
  989.   strcpy (tmp, str);
  990.   return tmp;
  991. }
  992.